package com.vito.oa.act.extend.service.impl;

import java.text.MessageFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.dubbo.config.annotation.Service;
import com.vito.act.tool.ActivitiContants;
import com.vito.base.authoriza.model.UserModel;
import com.vito.base.authoriza.service.UserService;
import com.vito.base.model.MyHashMap;
import com.vito.base.msg.dao.MsgTipsMapper;
import com.vito.base.msg.model.MsgTipsModel;
import com.vito.base.msg.service.MsgMqService;
import com.vito.base.msg.service.MsgSmsService;
import com.vito.base.util.DateUtils;
import com.vito.base.util.StringUtil;
import com.vito.base.util.Validata;
import com.vito.mq.ytx.MsgYtxGroupTools;
import com.vito.oa.act.constant.OaActContants;
import com.vito.oa.act.extend.dao.OaActExBussMapper;
import com.vito.oa.act.extend.dao.OaActExDataMapper;
import com.vito.oa.act.extend.model.OaActExBussModel;
import com.vito.oa.act.extend.service.OaActExMsgService;
@Service(group="OaActExMsgServiceImpl")
public class OaActExMsgServiceImpl implements OaActExMsgService {
	private static final Logger log = LoggerFactory.getLogger(OaActExMsgServiceImpl.class);

	@Autowired
	private OaActExBussMapper actExBussMapper;
	@Autowired
	private OaActExDataMapper actExDataMapper;
	@Autowired
	private MsgMqService msgMqService;
	@Autowired
	private UserService userService;
	@Autowired
	private MsgSmsService msgSmsService;
	@Autowired
	private MsgTipsMapper msgTipsMapper;
	@Autowired
	private com.vito.base.msg.service.MsgYtxService msgYtxService;
	
	//定长线程池长度
	private static final int fixedThreadCount = 3;
	private static ExecutorService fixedThreadPool = Executors.newFixedThreadPool(fixedThreadCount);
	private final String msgTextStart = "您已成功发起{0}，发起时间：{1}，下一步处理人：{2}，请知晓。";
	private final String msgTextNext = "您有待处理的{0}，发起人：{1}，发起时间：{2}，请及时处理。";
	private final String msgTextEnd = "您发起的{0}已处理完成，发起时间：{1}，请知晓。";
	private final String msgTextCC = "收到一份抄送您的{0}，发起时间：{1}，请知晓。";
	
	@Override
	public void sendActExMsg(final String startUser,final String nextUser,final String processKey,final String bussId) {
		fixedThreadPool.execute(new Runnable() {
			@Override
			public void run() {
				try {
					sendMsg(startUser, nextUser,processKey, bussId);
				} catch (Exception e) {
					log.error("流程处理消息发送异常：", e);
				}
			}
		});
	}

	@Override
	public void sendActMsgToCCuser(final String startUser, final String processKey, final String bussId,final String[] users) {
		fixedThreadPool.execute(new Runnable() {
			@Override
			public void run() {
				try {
					Map<String,String> info = queryApprovalInfo(startUser,processKey,bussId);
					String msgType = info.get("msgType");
					String moudelName = info.get("moudelType");
					String processName = info.get("processName");
					String ccText = MessageFormat.format(msgTextCC, processName,info.get("startTime"));
					Map<String, String> map = new HashMap<String, String>();
					MsgTipsModel msg = new MsgTipsModel();
					msg.setMsgType("oa");
					msg.setAfterOpen("open_page");
					msg.setSysType("oa");
					msg.setMsgTicker(moudelName);
					msg.setMsgTitle(processName);
					msg.setUserId(startUser);
					if(ActivitiContants.PROCESS_MSG_TYPE_SMS.equals(info)){
						map.put("sysType", "oa");
						map.put("smsType", "1");
						map.put("priority", "1");
						map.put("smsText",ccText);
					}else if(ActivitiContants.PROCESS_MSG_TYPE_UMENG.equals(msgType)){
						map.put("sysType", "oa");
						map.put("appType", ActivitiContants.PROCESS_MSG_TYPE_UMENG);
						map.put("afterOpen", "go_todo");
						map.put("msgTicker", moudelName);
						map.put("msgTitle", processName);
						map.put("msgText", ccText);
					}else if(ActivitiContants.PROCESS_MSG_TYPE_RLYTX.equals(msgType)){
						String sender = getYtxSender(info.get("moudelType"));
						if(sender != null){
							map.put("pushType", "1");
							map.put("msgType", "1");
							map.put("sender",sender);
							map.put("userId", sender);
							map.put("msgFileUrl", "/act/mobile/schedule.HTML");
							map.put("msgFileName", moudelName);
							map.put("msgDomain", processName);
							map.put("msgContent", ccText);
						}
					}else if(ActivitiContants.PROCESS_MSG_TYPE_MQ.equals(msgType)){
						return;
					}else if(ActivitiContants.PROCESS_MSG_TYPE_EMAIL.equals(msgType)){
						return;
					}else{
						return;
					}
					sendMsgToCCUsers(map, bussId, ccText, msgType, msg,users);
				} catch (Exception e) {
					log.error("流程处理消息发送异常：", e);
				}
			}
		});
	}
	
	public void sendMsg(String startUser,String nextUser,String processKey,String bussId){
		
		Map<String,String> info = queryApprovalInfo(startUser,processKey,bussId);
		String startTime = info.get("startTime");
		String startUserName =  info.get("startUserName");
		String msgType = info.get("msgType");
		String moudelName = info.get("moudelName");
		String processName = info.get("processName");
		
		//下一步处理人
		UserModel next=null;
		if(Validata.notNullOrEmpty(nextUser)){
			next = new UserModel();
			next.setUserId(nextUser);
			List<UserModel> nextList = userService.queryByUser(next);
			if(!nextList.isEmpty()){
				next = nextList.get(0);
			}
		}
		
		Map<String, String> map = new HashMap<String, String>();
		MsgTipsModel msg = new MsgTipsModel();
		msg.setMsgType("oa");
		msg.setAfterOpen("open_page");
		msg.setSysType("oa");
		msg.setMsgTicker(moudelName);
		msg.setMsgTitle(processName);
		msg.setUserId(startUser);
		if(ActivitiContants.PROCESS_MSG_TYPE_SMS.equals(msgType)){
			map.put("sysType", "oa");
			map.put("smsType", "1");
			map.put("priority", "1");
			//下一步流程人为空，说明改工单已完结
			if(next == null){
				//发送消息给流程发起人
				map.put("smsText", MessageFormat.format(msgTextEnd, processName,startTime));
				sendSms(map,startUser,msg);
			}else{
				//给发起人
				map.put("smsText", MessageFormat.format(msgTextStart, processName,startTime,next.getUserName()));
				sendSms(map,startUser,msg);
				//给下步处理人
				map.put("smsText", MessageFormat.format(msgTextNext, processName,startUserName,startTime));
				sendSms(map,nextUser,msg);
			}
		}else if(ActivitiContants.PROCESS_MSG_TYPE_UMENG.equals(msgType)){
			map.put("sysType", "oa");
			map.put("appType", ActivitiContants.PROCESS_MSG_TYPE_UMENG);
			map.put("afterOpen", "go_todo");
			map.put("msgTicker", moudelName);
			map.put("msgTitle", processName);
			if(next == null){
				map.put("msgText", MessageFormat.format(msgTextEnd, processName,startTime));
				sendUmeng(map,startUser,msg);
			}else{
				map.put("msgText", MessageFormat.format(msgTextStart, processName,startTime,next.getUserName()));
				sendUmeng(map,startUser,msg);
				map.put("msgText", MessageFormat.format(msgTextNext, processName,startUserName,startTime));
				sendUmeng(map,nextUser,msg);
			}
		}else if(ActivitiContants.PROCESS_MSG_TYPE_RLYTX.equals(msgType)){
			
			String sender = getYtxSender(info.get("moudelType"));
			if(sender != null){
				map.put("pushType", "1");
				map.put("msgType", "1");
				map.put("sender",sender);
				map.put("userId", sender);
				map.put("msgFileUrl", "/act/mobile/schedule.HTML");
				map.put("msgFileName", moudelName);
				map.put("msgDomain", processName);
				if(next == null){
					map.put("msgContent", MessageFormat.format(msgTextEnd,processName,startTime));
					sendRlytx(map,startUser);
				}else{
					map.put("msgContent", MessageFormat.format(msgTextStart, processName,startTime,next.getUserName()));
					sendRlytx(map,startUser);
					map.put("msgContent", MessageFormat.format(msgTextNext, processName,startUserName,startTime));
					sendRlytx(map,nextUser);
				}
			}
		}else if(ActivitiContants.PROCESS_MSG_TYPE_MQ.equals(msgType)){
			return;
		}else if(ActivitiContants.PROCESS_MSG_TYPE_EMAIL.equals(msgType)){
			return;
		}else{
			return;
		}
	}
	
	private void sendMsgToCCUsers(Map<String, String> map,String bussId,String ccText, String msgType, MsgTipsModel msg,String[] ccUsers) {
		//同时推送消息给抄送人
//		List<Map<String, String>> ccUsers = oaActCCMapper.queryCCUsers(bussId);
		if(ccUsers!=null&&ccUsers.length > 0){
			log.info("同时推送消息给抄送人,推送方式：" + msgType);
			for(String user : ccUsers){
				if (ActivitiContants.PROCESS_MSG_TYPE_SMS.equals(msgType)) {
					map.put("smsText", ccText);
					sendSms(map, user, msg);
				} else if(ActivitiContants.PROCESS_MSG_TYPE_MQ.equals(msgType)){
					//暂无
				} else if (ActivitiContants.PROCESS_MSG_TYPE_UMENG.equals(msgType)) {
					map.put("msgText", ccText);
					sendUmeng(map, user, msg);
				} else if (ActivitiContants.PROCESS_MSG_TYPE_EMAIL.equals(msgType)) {
					//暂无
				} else if (ActivitiContants.PROCESS_MSG_TYPE_RLYTX.equals(msgType)) {
					map.put("msgContent", ccText);
					sendRlytx(map, user);
				}
			}
		}
	}
	
	private Map<String,String> queryApprovalInfo(String startUser,String processKey,String bussId){
		OaActExBussModel bussModel = new OaActExBussModel();
		bussModel.setProcessKey(processKey);
		bussModel = actExBussMapper.queryActExBussByProcessKey(bussModel);
		if(bussModel==null){
			log.debug("未查询到流程");
			return null;
		}
		String startTime = null;
		String startUserName = null;
		List<MyHashMap<String, String>> dataList = actExDataMapper.queryActExDataByBussId(bussId);
		if(dataList==null||dataList.size()==0){
			UserModel next = new UserModel();
			next.setUserId(startUser);
			List<UserModel> user = userService.queryByUser(next);
			if(user!=null&&user.size()>0){
				startUserName = user.get(0).getUserName();
			}
			startTime = StringUtil.getDate("yyyy-MM-dd HH:mm:ss");
		}else{
			//发起人
			startUser = dataList.get(0).get("userid");
			startTime =dataList.get(0).get("starttime");
			startUserName = dataList.get(0).get("username");
		}
		Map<String,String> info = new HashMap<>();
		info.put("businessId",bussId);
		info.put("processKey",processKey);
		info.put("startUser",startUser);
		info.put("startUserName",startUserName);
		info.put("startTime",startTime);
		info.put("processName",bussModel.getProcessName());
		info.put("msgType", bussModel.getMsgType());
		info.put("moudelType", bussModel.getMoudelType());
		info.put("moudelName", bussModel.getMoudelName());
		
		return info;
	}
	
	/**
	 * 容联推送
	 * @param map
	 * @param userId
	 * @param msg
	 */
	private void sendRlytx(Map<String, String> map, String userId) {
		log.debug(map.get("msgContent"));
		map.put("receiver", userId);
		msgYtxService.addImMsg(map);
	}
	
	/**
	 * 友盟推送
	 * @param map
	 * @param userId
	 * @param msg
	 */
	private void sendUmeng(Map<String, String> map, String userId, MsgTipsModel msg) {
		String msgStr  = map.get("smsText");
		log.debug(msgStr);
		map.put("userIds", userId);
		msgMqService.addTask(map);
		msg.setSendUserId(userId);				
		msg.setMsgText(msgStr);
		msg.setMsgId(StringUtil.getUUID());
		msg.setSendTime(DateUtils.getTimstampDate());
		msgTipsMapper.insertMsgTips(msg);
	}
	/**
	 * 发送短信
	 * @param map
	 * @param userId 接收人
	 * @param msg 消息体
	 */
	private void sendSms(Map<String, String> map, String userId, MsgTipsModel msg){
		String msgStr  = map.get("smsText");
		log.debug(msgStr);
		map.put("userId", userId);
		msgSmsService.addTask(map);
		msg.setSendUserId(userId);				
		msg.setMsgText(msgStr);
		msg.setMsgId(StringUtil.getUUID());
		msg.setSendTime(DateUtils.getTimstampDate());
		msgTipsMapper.insertMsgTips(msg);
	}
	/**
	 * 根据所属应用模块获取sender
	 * @param moudelType 所属模块
	 * @return
	 */
	private String getYtxSender(String moudelType){
		String sender = null;
		switch(moudelType){
		case OaActContants.PROCESS_MOUDEL_TYPE_APPROVAL:
			 sender = MsgYtxGroupTools.url.getProp("sender.approval"); 
			break;
		case OaActContants.PROCESS_MOUDEL_TYPE_DOCUMENT:
			sender = MsgYtxGroupTools.url.getProp("sender.document");
			break;
		default:
			break;
		}
		return sender;
	}

}
